package pl.kosmowska.ewelina.client.views.widgets;
import pl.kosmowska.ewelina.client.ViewMessages;
import pl.kosmowska.ewelina.client.app.requestfactory.CategoryDataRequest;
import pl.kosmowska.ewelina.client.app.requestfactory.dto.CategoryDataProxy;
import pl.kosmowska.ewelina.client.views.widgets.dialogs.BooleanDialog;
import pl.kosmowska.ewelina.client.views.widgets.dialogs.BooleanEvent;
import pl.kosmowska.ewelina.client.views.widgets.dialogs.BooleanEvent.Selected;
import pl.kosmowska.ewelina.client.views.widgets.dialogs.BooleanEventHandler;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemAddedEvent;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemAddedHandler;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemEditedEvent;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemEditedHandler;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SimpleHtmlSanitizer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.Widget;

public abstract class CategoryWidget extends Composite {

	private static CategoryWidgetUiBinder uiBinder = GWT
			.create(CategoryWidgetUiBinder.class);

	interface CategoryWidgetUiBinder extends UiBinder<Widget, CategoryWidget> {
	}

	final private HandlerManager handlerManager = new HandlerManager(this);
	public static enum State {
		VIEW, EDIT;
	}
	private State stateIs;

	@UiField TextBox tbNameBox;
	@UiField Label tbNameLbl;
	@UiField FocusPanel pFocus;
	@UiField Image editImg;
	@UiField Image deleteImg;
	@UiField Image addImg;


	private CategoryDataProxy categoryData;
	private BooleanDialog wconfirm;
	TreeItem categoryRoot;
	TreeItem itemRoot;


	public CategoryWidget(TreeItem categoryRoot) {
		initWidget(uiBinder.createAndBindUi(this));
		setTitle("Dodaj kategorię");
		this.categoryRoot=categoryRoot;
		tbNameBox.addKeyDownHandler(new KeyDownHandler() {
			@Override
			public void onKeyDown(KeyDownEvent event) {
				if(KeyCodes.KEY_ENTER == event.getNativeKeyCode()) {
					setStateView() ;
					fireItemEditedChange();
				}
			}
		});	 
	}
	public void setStateView() {
		tbNameBox.setVisible(false);
		tbNameLbl.setVisible(true);
		stateIs=State.VIEW;
	}

	private void setStateEdit() {
		tbNameBox.setVisible(true);
		tbNameLbl.setVisible(false);
		stateIs=State.EDIT;
	}

	public void setData(int i, CategoryDataProxy itemData) {
		this.categoryData = itemData;
		if(categoryData!=null){
			tbNameLbl.setText(categoryData.getName());
			tbNameBox.setText(categoryData.getName());
			if(categoryData.isDefaultCategory()){
				editImg.setVisible(false);
				deleteImg.setVisible(false);
			}
			setStateView();	    
		}else{
			setStateEdit();
		}

	}

	public CategoryDataProxy getData(CategoryDataRequest request) {
		if (categoryData == null) {
			categoryData = request.create(CategoryDataProxy.class);
		} else {
			categoryData = request.edit(categoryData);
		}

		categoryData.setName(getName());
		return categoryData;
	}


	private String getName() {
		String s = tbNameBox.getText().trim();
		if (s.length() == 0) {
			s = null;
		}
		return s;
	}

	public void draw() {
		setStateView() ;
		drawName();
	}

	private void drawName() {
		if (categoryData == null || 
				categoryData.getName() == null || 
				categoryData.getName().trim().length() == 0) {
			setStateEdit();
			return;
		}

		String s = categoryData.getName();
		SafeHtml sh = SimpleHtmlSanitizer.sanitizeHtml(s);
		tbNameLbl.setText(sh.asString());
		tbNameBox.setText(sh.asString());
	}

	private void delete() {
		if (wconfirm == null) {
			wconfirm = new BooleanDialog(ViewMessages.CONFIRM_DELETE);
			wconfirm.addSelectionHandler(new BooleanEventHandler() {
				public void onBooleanEvent(BooleanEvent event) {
					if (event.getBooleanEvent() == Selected.TRUE) {
						deleteIt();
					} else if (event.getBooleanEvent() == Selected.FALSE) {
						// do nothing
					}
				}
			});
		}
		wconfirm.center();
	}

	public abstract void deleteIt();


	private void fireItemCreatedChange() {
		handlerManager.fireEvent(new ItemAddedEvent());
	}

	private void fireItemEditedChange() {
		handlerManager.fireEvent(new ItemEditedEvent());
	}

	public HandlerRegistration addChangeHandler(ChangeHandler handler) {
		return addDomHandler(handler, ChangeEvent.getType());
	}


	@UiHandler("deleteImg")
	void onDeleteImg2Click(ClickEvent event) {
		delete();
	}
	@UiHandler("editImg")
	void onEditImgClick(ClickEvent event) {
		if(stateIs== State.VIEW)
			setStateEdit();
		else
			setStateView();
	}

	@UiHandler("addImg")
	void onAddImgClick(ClickEvent event) {
		fireItemCreatedChange();
	}

	public void setTreeItem(TreeItem mailPanelRoot) {
		itemRoot=mailPanelRoot;		
	}

	public void removeFromTree() {
		categoryRoot.removeItem(itemRoot);

	}

	public void addItemAddedHandler(ItemAddedHandler handler) {
		handlerManager.addHandler(ItemAddedEvent.getType(),handler);  
	}

	public void addItemEditedHandler(ItemEditedHandler handler) {
		handlerManager.addHandler(ItemEditedEvent.getType(),handler);  
	}
	public CategoryDataProxy getCategoryData() {
		return categoryData;
	}



}

